package com.practice.zookeeper.client.zk;

import java.util.ArrayList;
import java.util.List;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;

import com.practice.zookeeper.client.zk.loadbalance.LoadBalance;
import com.practice.zookeeper.client.zk.loadbalance.RandomLoadBalance;
import com.practice.zookeeper.server.zk.ZKConfig;

public class ServiceDiscoveryImpl implements IServiceDiscovery {
	
	private List<String> repos = new ArrayList<>();
	
	private String address;
	
	private CuratorFramework curatorFramwork;

	public ServiceDiscoveryImpl(String address) {
		this.address = address;
		
		curatorFramwork = CuratorFrameworkFactory.builder()
				.connectString(address)
				.sessionTimeoutMs(4000)
				.retryPolicy(new ExponentialBackoffRetry(1000, 10))
				.build();
		curatorFramwork.start();
	}

	@Override
	public String discovery(String serviceName) {
		String path = ZKConfig.ZK_REGISTER_PATH + "/" + serviceName;
		try {
			repos = curatorFramwork.getChildren().forPath(path);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		registryWatcher(path);
		
		LoadBalance balance = new RandomLoadBalance();
		return balance.selectHost(repos);
	}
	
	@SuppressWarnings("resource")
	private void registryWatcher(String path) {
		PathChildrenCache cache = new PathChildrenCache(curatorFramwork, path, true);
		
		PathChildrenCacheListener listen = new PathChildrenCacheListener() {
			
			@Override
			public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent event) throws Exception {
				repos = curatorFramework.getChildren().forPath(path);
			}
		};
		cache.getListenable().addListener(listen);
		try {
			cache.start();
		} catch (Exception e) {
			throw new RuntimeException("注册 PathChildren Watcher异常" + e);
		}
	}

}
